import { useState, useEffect } from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
import { PowerData } from '@/types/data';
import useInterval from '@/hooks/useInterval';
import { toast } from 'sonner';

export default function PowerChart() {
  const [displayData, setDisplayData] = useState<PowerData[]>([]);
  const [fullData, setFullData] = useState<PowerData[]>([]);
  const [isPredicting, setIsPredicting] = useState(false);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [isLoading, setIsLoading] = useState(true);

 
  useEffect(() => {
    const loadData = async () => {
      try {
  
        const dataUrl = import.meta.env.PROD ? '/datas.txt' : '/datas.txt';
        const response = await fetch(dataUrl, {
          headers: {
            'Accept': 'text/plain',
            'Content-Type': 'text/plain',
            'Cache-Control': 'no-cache'
          },
          credentials: 'same-origin',
          redirect: 'error' 
        });

 
        if (!response.ok && response.status === 404) {
          toast.info('如果修改了public目录下的文件，可能需要重启开发服务器');
        }

 
        if (!response.ok) {
          const errorText = await response.text();
          if (errorText.includes('<html') || errorText.includes('<!DOCTYPE')) {
            throw new Error('服务器返回HTML错误页面而非数据文件，请检查:\n1. datas.txt文件是否存在于public目录\n2. Vite服务器是否已重启\n3. 文件路径是否正确');
          }
          throw new Error(`HTTP错误! 状态码: ${response.status}\n请检查:\n1. datas.txt文件是否存在于public目录\n2. 服务器是否有访问权限`);
        }

        const contentType = response.headers.get('content-type');
        const responseText = await response.text();
        
        if (!contentType || !contentType.includes('text/plain') || responseText.includes('<html') || responseText.includes('<!DOCTYPE')) {
          throw new Error(`数据加载失败: 服务器返回${contentType || '未指定内容类型'}\n请执行以下检查:\n1. 确认datas.txt文件存在于public目录\n2. 重启开发服务器(pnpm dev)\n3. 检查文件内容是否为纯文本格式\n\n正确格式示例:\nActual Load Predicted Load\n346.936 415.9295653788965\n334.751 377.31242502703`);
        }

 
        let content = responseText.trim();
        if (content.charCodeAt(0) === 0xFEFF) {
          content = content.substring(1).trim();
        }

        if (content.length === 0) {
          throw new Error('数据文件为空');
        }

        const lines = content.split(/\r?\n/).filter(line => line.trim() !== '');
        
        if (lines.length < 2) {
          throw new Error('数据文件内容不足，至少需要一行表头和一行数据');
        }

  
        const header = lines[0].trim();
        if (!header.includes('Load') || !header.includes('Predicted')) {
          console.warn('表头格式可能与预期不符:', header);
        }


        const parsedData = [];
        const batchSize = 20; 
        let lineIndex = 1;
        
        while (lineIndex < lines.length) {
          const batchEnd = Math.min(lineIndex + batchSize, lines.length);
          
          for (let i = lineIndex; i < batchEnd; i++) {
            const line = lines[i].trim();
            if (!line) continue;
            

            const values = line.split(/\s+/).filter(v => v !== '');
            
            if (values.length < 2) {
              console.error('解析失败的行数据:', line);
              throw new Error(`第${i+1}行数据格式错误，需要两列数据(实际负荷和预测负荷)\n示例格式: 346.936 415.9295653788965\n当前行: ${line}`);
            }

            const actual = parseFloat(values[0]);
            const predicted = parseFloat(values[1]);
            
            if (isNaN(actual) || isNaN(predicted)) {
              console.error('无效数值:', values[0], values[1]);
              throw new Error(`第${i+1}行数值解析失败: 实际负荷=${values[0]}, 预测负荷=${values[1]}\n请确保数据为有效数字`);
            }

            parsedData.push({
              timestamp: `${i}`,
              actual: Number(actual.toFixed(2)),
              predicted: Number(predicted.toFixed(2))
            });
          }
          
          lineIndex = batchEnd;

          setDisplayData(parsedData.slice(-100));
          await new Promise(resolve => setTimeout(resolve, 100)); 
        }

        if (parsedData.length === 0) {
          throw new Error('没有找到有效数据');
        }

        setFullData(parsedData);
        toast.success(`成功加载 ${parsedData.length} 条数据`);
      } catch (error) {
        console.error('数据加载错误:', error);
        toast.error(`数据加载失败: ${error instanceof Error ? error.message : '未知错误'}\n请检查:\n1. datas.txt文件是否存在于public目录\n2. 文件格式是否正确\n3. 服务器配置是否正确\n\n正确格式要求:\n- 第一行应为表头\n- 后续每行包含两个数值(实际负荷和预测负荷)\n示例格式: 346.936 415.9295653788965`);
      } finally {
        setIsLoading(false);
      }
    };

    loadData();
  }, []);

  // 开始/停止预测
  const togglePrediction = () => {
    setIsPredicting(!isPredicting);
    if (!isPredicting) {
      setCurrentIndex(20); // 从第20条开始滚动
    }
  };

  // 数据滚动显示
  useInterval(() => {
    if (isPredicting && currentIndex < fullData.length) {
      setDisplayData(prev => {
        const newData = [...prev.slice(1), fullData[currentIndex]];
        return newData.length > 100 ? newData.slice(-100) : newData;
      });
      setCurrentIndex(prev => prev + 1);
    } else if (currentIndex >= fullData.length) {
      setIsPredicting(false);
      toast.info('数据展示完成');
    }
  }, isPredicting ? 2000 : null); // 1000ms = 1组/秒

  if (isLoading) {
    return (
      <div className="flex flex-col h-full items-center justify-center">
        <div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
        <p className="mt-4 text-gray-400">数据加载中...</p>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full">
      <div className="flex justify-between items-center mb-4">
        <h2 className="text-xl font-medium font-['Google_Sans']">电力负荷预测</h2>
        <button 
          className={`${isPredicting ? 'bg-red-600 hover:bg-red-700' : isLoading ? 'bg-gray-500 cursor-not-allowed' : 'bg-blue-600 hover:bg-blue-700'} text-white px-4 py-2 rounded-lg transition-all duration-200`}
          onClick={togglePrediction}
          disabled={isLoading}
        >
          {isLoading ? '数据加载中...' : isPredicting ? '停止预测' : '开始预测'}
        </button>
      </div>
      <div className="flex-1 min-h-[400px]">
        <ResponsiveContainer width="100%" height="100%">
          <LineChart data={displayData}>
            <CartesianGrid strokeDasharray="3 3" stroke="#444" />
            <XAxis 
              dataKey="timestamp" 
              stroke="#aaa"
              tick={{ fontSize: 12 }}
              interval={Math.floor(100 / 12)}  // 每48个点(2小时)显示一个刻度
              tickFormatter={(value) => {
                const day = Math.floor(parseInt(value) / 100) + 1;
                const hour = (parseInt(value) % 24);
                return hour % 2 === 0 ? `Day ${day} ${hour}:00` : '';
              }}
            />
             <YAxis 
              stroke="#aaa"
              tickFormatter={(value) => value.toFixed(2)}
              domain={[-200, 650]}
            />
            <Tooltip 
              contentStyle={{ 
                backgroundColor: '#333',
                borderColor: '#555',
                borderRadius: '8px'
              }}
              formatter={(value, name) => [Number(value).toFixed(2), name === 'actual' ? '实际负荷' : '预测负荷']}
              labelFormatter={(label) => {
                const day = Math.floor(parseInt(label) / 100) + 1;
                const hour = parseInt(label) % 24;
                return `Day ${day} ${hour.toString().padStart(2, '0')}:00`;
              }}
            />
            <Legend />

            <Line 
              type="monotone" 
              dataKey="actual" 
              name="实际负荷"
              stroke="#00E5FF" 
              strokeWidth={2}
              dot={{ r: 2 }}
              activeDot={{ r: 6 }}
              isAnimationActive={false}
            />
            <Line 
              type="monotone" 
              dataKey="predicted" 
              name="预测负荷"
              stroke="#FF0080" 
              strokeWidth={2}
              strokeDasharray="5 5"
              dot={{ r: 2 }}
              isAnimationActive={false}
            />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}
